﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;
using MPMovieCatalog.Forms;

namespace MPMovieCatalog.Util
{
    public class ProgressWorker : IDisposable
    {
        private ProgressForm m_progressForm;

        private BackgroundWorker m_backgroundWorker;

        private IWorkable m_workable;

        public ProgressWorker(IWorkable workable)
        {
            m_workable = workable;

            m_progressForm = new ProgressForm();
            m_progressForm.Text = m_workable.Title;

            m_progressForm.Shown += new System.EventHandler(this.OnShown);
            m_progressForm.Cancel += new System.EventHandler(this.OnCancel);

            m_backgroundWorker = new BackgroundWorker();
            m_backgroundWorker.WorkerReportsProgress = true;
            m_backgroundWorker.WorkerSupportsCancellation = true;
            m_backgroundWorker.DoWork += new DoWorkEventHandler(DoWork);
            m_backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(ProgressChanged);
            m_backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted);
        }

        public void Start()
        {
            m_progressForm.ShowDialog();
        }

        public void OnProgress(int percentProgress, string label)
        {
            m_backgroundWorker.ReportProgress(percentProgress, label);
        }

        public bool CancellationPending
        {
            get
            {
                return m_backgroundWorker.CancellationPending;
            }
        }

        private void DoWork(object sender, DoWorkEventArgs e)
        {
            e.Result = m_workable.DoWork(this);
            e.Cancel = m_workable.IsCancelled;
        }

        private void ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            m_progressForm.Percentage = e.ProgressPercentage;
            m_progressForm.Label = e.UserState.ToString();
        }

        private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(m_progressForm, e.Error.Message, ResourceUtils.GetString("common", 0), MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else if (e.Cancelled)
            {
                MessageBox.Show(m_progressForm, ResourceUtils.GetString("common", 4), ResourceUtils.GetString("common", 2), MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else if (e.Result != null && !string.IsNullOrEmpty(e.Result.ToString()))
            {
                MessageBox.Show(m_progressForm, e.Result.ToString(), ResourceUtils.GetString("common", 2), MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            m_progressForm.Close();
        }

        private void OnCancel(object sender, EventArgs e)
        {
            m_backgroundWorker.CancelAsync();
        }

        private void OnShown(object sender, EventArgs e)
        {
            m_backgroundWorker.RunWorkerAsync();
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (m_progressForm != null)
            {
                m_progressForm.Dispose();
            }

            if (m_backgroundWorker != null)
            {
                m_backgroundWorker.Dispose();
            }
        }

        #endregion
    }


    public interface IWorkable
    {
        string DoWork(ProgressWorker worker);
        string Title { get; }
        bool IsCancelled { get; }
    }
}
